package com.ruoyi.file.controller;

import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.file.utils.UrlToMultipartFileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.server.ResponseStatusException;

import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.io.IOException;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.file.domain.Kv;
import com.ruoyi.file.dto.FileAttachmentInfoDto;
import com.ruoyi.file.vo.FileAttachmentInfoVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.RequiresPermissions;
import com.ruoyi.file.domain.FileAttachmentInfo;
import com.ruoyi.file.service.IFileAttachmentInfoService;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import java.io.*;
import java.util.Base64;
import java.net.URL;

/**
 * 附件信息Controller
 *
 * @author liyuxi
 * @date 2024-05-20
 */
@Api(value = "附件管理", tags = "附件管理接口")
@RestController
@RequestMapping("/fileAttachmentInfo")
public class FileAttachmentInfoController extends BaseController {
    @Autowired
    private IFileAttachmentInfoService fileAttachmentInfoService;

    @ApiOperation("通用附件上传 营业执照传businessLicense  身份证号传idCard")
    @PostMapping("/uploadFile")
    public AjaxResult uploadAttachment(HttpServletRequest request,
                                       @ApiParam(value = "文件", required = true) @RequestParam(value = "file", required = true) MultipartFile file,
                                       @ApiParam(value = "表名", required = true) @RequestParam(value = "tableName", required = true) String tableName,
                                       @ApiParam(value = "列名", required = true) @RequestParam(value = "colName", required = true) String colName,
                                       @ApiParam(value = "表值 关联ID", required = true) @RequestParam(value = "associationId", required = true) String associationId,
                                       @ApiParam(value = "水印", required = false) @RequestParam(value = "watermark", required = false) String watermark
    ) throws Exception {

        if (StringUtils.isEmpty(file.getOriginalFilename())) {
            return AjaxResult.error("上传文件为空");
        }
        if (StringUtils.isEmpty(associationId) || StringUtils.isEmpty(colName) || StringUtils.isEmpty(tableName)) {
            return AjaxResult.error("必填字段不可为空");
        }


        if (associationId.length() < 5) {
            return AjaxResult.error("associationId值不对");
        }

        try {
            HashMap<String, Object> stringObjectHashMap = fileAttachmentInfoService.uploadAttachment(file, tableName, colName, associationId, watermark);
            return success(stringObjectHashMap);
        } catch (Exception e) {
            e.printStackTrace();
            return error("保存失败");
        }
    }

    @ApiOperation("通过URL转成图片 上传文件到服务器")
    @PostMapping("/uploadFromUrl")
    public AjaxResult uploadFromUrl(
            @ApiParam(value = "文件URL", required = true) @RequestParam String url,
            @ApiParam(value = "表名", required = true) @RequestParam String tableName,
            @ApiParam(value = "列名", required = true) @RequestParam String colName,
            @ApiParam(value = "关联ID", required = true) @RequestParam String associationId,
            @ApiParam(value = "水印", required = false) @RequestParam(required = false) String watermark
    ) {
        try {
            // 将URL转换为MultipartFile
            MultipartFile file = UrlToMultipartFileUtil.convert(url);

            // 调用原有的上传逻辑
            HashMap<String, Object> result = fileAttachmentInfoService.uploadAttachment(
                    file, tableName, colName, associationId, watermark);

            return success(result);
        } catch (Exception e) {
            e.printStackTrace();
            return error("文件上传失败: " + e.getMessage());
        }
    }


    /**
     * 查询附件信息列表
     */
    @ApiOperation("查看单据的所有附件")
//    @RequiresPermissions("file:fileAttachmentInfo:list")
    @GetMapping("/list")
    public TableDataInfo list(FileAttachmentInfoDto fileAttachmentInfoDto) throws IOException {
        startPage();
        List<FileAttachmentInfoVo> list = fileAttachmentInfoService.selectFileAttachmentInfoList(fileAttachmentInfoDto);
        return getDataTable(list);
    }


    @ApiOperation("获取附件信息详细信息")
    @GetMapping("/getFileInfoById")
    public AjaxResult getFileInfoById(@ApiParam(value = "文件ID", required = true) @RequestParam(value = "id") String id) {
        return success(fileAttachmentInfoService.selectFileAttachmentInfoById(id));
    }

    /**
     * 删除附件信息
     */
//    @RequiresPermissions("file:fileAttachmentInfo:remove")
    @Log(title = "附件信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids) {
        return toAjax(fileAttachmentInfoService.deleteFileAttachmentInfoByIds(ids));
    }


/*    @GetMapping("/fileDetails")
    public AjaxResult fileDetails(@ApiParam(value = "附件的id", required = true) @RequestParam(value = "ids", required = true) List<String> ids
    ) {
        List<Kv> kvs = null;
        try {
            kvs = fileAttachmentInfoService.fileDetails(ids, null, null);
        } catch (IOException e) {
            return error("参数错误");
        }
        return success(kvs);
    }*/


    @ApiOperation("通用根据文件key拿到图片 图片是预览而不是下载")
    @GetMapping(value = "/viewImage")
    public ResponseEntity<byte[]> viewImage(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key", required = true) String key) {
        try {
            // 从OBS下载文件并转换为字节数组
            byte[] obsFileBytes = fileAttachmentInfoService.getDownloadUrl(key);

            // 设置HTTP头部
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_TYPE, "image/jpeg"); // 可以根据具体的图片类型调整
//            response.setContentType("image/jpeg");

            return new ResponseEntity<>(obsFileBytes, headers, HttpStatus.OK);
        } catch (Exception e) {
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "无法预览文件", e);
        }
    }

    @ApiOperation("通用根据文件key预览PDF文件")
    @GetMapping(value = "/viewPdf")
    public ResponseEntity<byte[]> viewPdf(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key", required = true) String key) {
        try {
            // 从OBS下载文件并转换为字节数组
            byte[] pdfFileBytes = fileAttachmentInfoService.getDownloadUrl(key);

            // 设置HTTP头部
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_TYPE, "application/pdf"); // 设置Content-Type为PDF类型
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"previewed_file.pdf\""); // 设置为inline以便浏览器预览

            return new ResponseEntity<>(pdfFileBytes, headers, HttpStatus.OK);
        } catch (Exception e) {
            throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "无法预览文件", e);
        }
    }


    @ApiOperation("通用根据文件key 拿到下载链接")
    @GetMapping(value = "/getObjectUrlByKey")
    public AjaxResult getObjectUrlByKey(
            @ApiParam(value = "key", required = true)
            @RequestParam(value = "key", required = true) String key) {
        try {
            // 从OBS下载文件并转换为字节数组
            String url = fileAttachmentInfoService.getObjectUrlByKey(key);
            return success(url);
        } catch (Exception e) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "无法下载文件", e);
        }
    }


    @ApiOperation("根据图片 URL 预览图片（直接在浏览器打开）")
    @GetMapping("/preview")
    public ResponseEntity<byte[]> previewImage(@RequestParam String imageUrl) {
        try (InputStream inputStream = new URL(imageUrl).openStream();
             ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {

            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, length);
            }

            byte[] imageBytes = outputStream.toByteArray();

            // 自动判断图片类型
            String contentType = URLConnection.guessContentTypeFromName(imageUrl);
            if (contentType == null) {
                contentType = "image/jpeg"; // fallback 默认
            }

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(contentType));
            return new ResponseEntity<>(imageBytes, headers, HttpStatus.OK);

        } catch (IOException e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    @ApiOperation("返回图片预览链接")
    @GetMapping("/previewPath")
    public Map<String, Object> previewPath(@RequestParam String imageUrl) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 构造图片访问路径（假设你的服务端口是 8080）
            String previewUrl = "/api/image/view?imageUrl=" + URLEncoder.encode(imageUrl, "UTF-8");
            result.put("code", 200);
            result.put("previewUrl", previewUrl); // 返回这个路径
        } catch (UnsupportedEncodingException e) {
            result.put("code", 500);
            result.put("message", "编码失败");
        }
        return result;
    }

}
